package service

import (
	"fmt"
	"math/rand"
	"sync"
	"web-service-demo/registry"
)

// 保存依赖服务的URL
type providers struct {
	services map[string][]string //某个服务可能有多个URL
	mutex    *sync.RWMutex
}

//更新依赖服务
func (p *providers) update(patch registry.Patch) {
	//上写锁
	p.mutex.Lock()
	defer p.mutex.Unlock()

	//增加
	for _, patchEntry := range patch.Added {
		//不存在，则新建一个slice
		if _, ok := p.services[patchEntry.Name]; !ok {
			p.services[patchEntry.Name] = make([]string, 0)
		}
		//添加
		p.services[patchEntry.Name] = append(p.services[patchEntry.Name], patchEntry.URL)
	}

	//删除
	for _, patchEntry := range patch.Removed {
		if providerURLs, ok := p.services[patchEntry.Name]; ok {
			for i := range providerURLs {
				if providerURLs[i] == patchEntry.URL {
					p.services[patchEntry.Name] = append(providerURLs[:i], providerURLs[i+1:]...)
				}
			}
		}
	}
}

//获取依赖服务的URL
func (p *providers) get(name string) (string, error) {
	//上读锁
	p.mutex.RLock()
	providers, ok := p.services[name]
	p.mutex.RUnlock()

	if !ok {
		return "", fmt.Errorf("no providers available for service %v", name)
	}
	idx := int(rand.Float32() * float32(len(providers)))
	return providers[idx], nil
}
